package com.jiantong.work.impl.service;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.user.ext.LoginUser;
import com.jiantong.work.enums.DocumentsDeleteFlag;
import com.jiantong.work.enums.RetailBreedRecordStatus;
import com.jiantong.work.impl.dao.RetailBreedRecordDao;
import com.jiantong.work.model.RetailBreedRecord;
import com.jiantong.work.service.RetailBreedRecordReadService;
import io.terminus.boot.rpc.common.annotation.RpcProvider;
import io.terminus.common.model.PageInfo;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by mz on 25/7/17.
 *
 */
@Slf4j
@RpcProvider
@Service
public class RetailBreedRecordReadServiceImpl implements RetailBreedRecordReadService{

    private final RetailBreedRecordDao retailBreedRecordDao;

    @Autowired
    public RetailBreedRecordReadServiceImpl(RetailBreedRecordDao retailBreedRecordDao) {
        this.retailBreedRecordDao = retailBreedRecordDao;
    }

    @Override
    public Response<RetailBreedRecord> findById(Long id) {
        try{
            return Response.ok(retailBreedRecordDao.findById(id));
        }catch (Exception e){
            log.error("failed to find retail breed record by id case = {}", Throwables.getStackTraceAsString(e));
            return Response.fail("failed to find retail breed record by id");
        }
    }

    @Override
    public Response<Paging<RetailBreedRecord>> paging(Integer pageNo, Integer pageSize, Integer status, Long breedFactoryId) {
        try{

            PageInfo pageInfo = new PageInfo(pageNo,pageSize);
            Map<String , Object> criteria = Maps.newHashMap();
            criteria.put("breedFactoryId",breedFactoryId);
            if(status != null){
                criteria.put("status",status);
            }
            return Response.ok(retailBreedRecordDao.paging(pageInfo.getOffset(),pageInfo.getLimit(),criteria));
        }catch (Exception e){
            log.error("failed to paging retail breed record for a single , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to paging retail breed record for a single");
        }
    }

    /**
     *
     * @param pageNo 页码
     * @param pageSize 每页多少条
     * @param status 状态
     * @param breedFactoryId 养殖场ID
     * @param breedType 养殖类型
     * @param villageId 村id
     * @param start 从日期
     * @param end 到日期
     * @return
     */
    @Override
    public Response<Paging<RetailBreedRecord>> pagingMulti(Integer pageNo, Integer pageSize,
                                                           Integer status, Long breedFactoryId,
                                                           Integer breedType, Long villageId,
                                                           Date start, Date end) {
        try{
            PageInfo pageInfo = new PageInfo(pageNo,pageSize);
            Map<String , Object> criteria = Maps.newHashMap();
            if(start != null){
                criteria.put("start",start);
            }
            if(end != null){
                criteria.put("end",end);
            }

            if(status != null){
                criteria.put("status",status);
            }

            if(breedType != null){
                criteria.put("breedType",breedType);
            }

            if(villageId != null){
                criteria.put("villageId",villageId);
            }

            List<Long> breedFactoryIds = new ArrayList<>();
            if(breedFactoryId != null){
                breedFactoryIds.add(breedFactoryId);
            }else {
                LoginUser loginUser = UserUtil.getCurrentUser();
                breedFactoryIds = loginUser.getBreedFactoryIds();
            }
            if(!breedFactoryIds.isEmpty()) criteria.put("breedFactoryIds",breedFactoryIds);
            else return Response.ok(new Paging<>(0L,new ArrayList<>()));

            return Response.ok(retailBreedRecordDao.pagingMulti(pageInfo.getOffset(),pageInfo.getLimit(),criteria));
        }catch (Exception e){
            log.error("failed to paging retail breed record for multi , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to paging retail breed record");
        }
    }

    /**
     * 根据主键ID 查询单据的当前状态
     *
     * @param id 主键ID
     * @return Map<String,Integer>
     */
    @Override
    public Response<Map<String, Integer>> findStatusById(Long id) {
        try{
            Integer status = retailBreedRecordDao.findStatusById(id);
            if(status == null){
                log.error("status(id={}) is not found", id);
                return Response.fail("status.not.found");
            }
            Map<String ,Integer> map = Maps.newHashMap();
            map.put("status",status);
            return Response.ok(map);
        }catch (Exception e){
            log.error("failed to find status by id , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to find status by id");
        }
    }

    /**
     * 查询出一个是否免疫的list
     *
     * @param breedFactoryIds 养殖场ids
     * @return List<Boolean>
     */
    @Override
    public Response<List<Boolean>> countIsVaccine(List<Long> breedFactoryIds) {
        try{
            return Response.ok(retailBreedRecordDao.countIsVaccine(breedFactoryIds));
        }catch (Exception e){
            log.error("failed to count is vaccine case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to count is vaccine");
        }
    }

    /**
     * 分页查询多个养殖场的单据信息
     *
     * @param pageNo         页码
     * @param pageSize       每页多少条
     * @param status         状态
     * @param breedFactoryId 养殖场ID
     * @param breedType      养殖类型
     * @param villageId      村id
     * @param start          从日期
     * @param end            到日期
     * @return Paging<RetailBreedRecord>
     */
    @Override
    public Response<Paging<RetailBreedRecord>> pagingByVillage(Integer pageNo, Integer pageSize, Integer status, Long breedFactoryId, Integer breedType, Long villageId, Date start, Date end) {
        try{
            PageInfo pageInfo = new PageInfo(pageNo,pageSize);
            Map<String , Object> criteria = Maps.newHashMap();
            if(start != null){
                criteria.put("start",start);
            }
            if(end != null){
                criteria.put("end",end);
            }

            if(status != null){
                criteria.put("status",status);
            }

            if(breedType != null){
                criteria.put("breedType",breedType);
            }

            if(villageId != null){
                criteria.put("villageId",villageId);
            }

            List<Long> breedFactoryIds = new ArrayList<>();
            if(breedFactoryId != null){
                breedFactoryIds.add(breedFactoryId);
            }else {
                LoginUser loginUser = UserUtil.getCurrentUser();
                breedFactoryIds = loginUser.getBreedFactoryIds();
            }

            criteria.put("breedFactoryIds",breedFactoryIds);
            return Response.ok(retailBreedRecordDao.pagingByVillage(pageInfo.getOffset(),pageInfo.getLimit(),criteria));
        }catch (Exception e){
            log.error("failed to paging retail breed record for multi , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to paging retail breed record");
        }
    }
    /**
     * 溯源
     *
     * @param breedFactoryId 养殖场id
     * @param markNumber     耳标号（完整）
     * @return RetailBreedRecord
     */
    @Override
    public Response<RetailBreedRecord> findByMarkNumber(Long breedFactoryId, String markNumber) {
        try{
            Map<String , Object> criteria = Maps.newHashMap();
            criteria.put("breedFactoryId",breedFactoryId);
            criteria.put("markNumber",markNumber);
            criteria.put("deleteFlag", DocumentsDeleteFlag.NORMAL.value());
            criteria.put("status", RetailBreedRecordStatus.FINISHED.value());
            return Response.ok(retailBreedRecordDao.findByMarkNumber(criteria));
        }catch (Exception e){
            log.error("failed to find RetailBreedRecord by mark number , case = {}",Throwables.getStackTraceAsString(e));
            return Response.fail("failed to find RetailBreedRecord by mark number");
        }
    }
}
